<?php
/**
 * Controller_Default
 *
 * Класс отвечает за обработку запросов к страницам, для которых первое слово сходу не определяет контроллер
 *
 * @author Дмитрий Кузьма <kouzma.d@gmail.com>
 * @author Александр Егоров <slamer86@gmail.com>
 * @version 2.1
 */
class Controller_Default extends Controller_Base {
	
	/**
	 * Конструктор контроллера
	 *
	 * @param array $arrRequest - массив, содержащий информацию о запросе к странице (элементы массива  - то что между слешами в URL)
	 */
	public function __construct(&$arrRequest) {
	  Service_Debug::setDebug();
	  parent::__construct($arrRequest);
		$this->showLeftColumn = false;
	}	
	
	/**
	 * Выбираем действие исходя из URL
	 */
	public function action() {
	  Service_Debug::setDebug();	  
	  switch ($this->arrRequest[0]) {
	    case 'revision':
	    	$this->actionRevision();
	      break;   	
	    default:
	  	  $url = Service_Escape::absolutelyEscapeString($this->arrRequest[0]);
	  	  // Ищем статьи с таким URL
	    	$objArticle = new Article();
	      $objArticle->find('first', array('conditions' => "`article`.`url` = '" . $url . "' AND `article`.`is_hms` = 0"));
			  if (!$objArticle->id) throw new Exception_SiteError('', 404);	  
			  $this->actionArticle($objArticle);     	      	          
	  }
	}
	
	/**
	 * Выводит страницу статьи
	 * 
	 * @param Article $objArticle - Статья
	 */
	public function actionArticle(Article $objArticle) {
		Service_Debug::setDebug();
		$language = Service_Translate::getLang();
		
		// Обработка данных (заполнение формы)		
		$objData = new Data(isset($_POST['Data']) ? Service_Escape::absolutelyEscapeArray($_POST['Data']) : null);
		if (isset($_POST['Data'])) $this->processForm($objArticle->getField('url'), $objData);
		/*else { 
			switch ($objArticle->getField('url')) { // Заполняет специальные статьи
				case 'cancellation.htm': // Отмена бронирования
					$objData->setField('id', Service_Escape::requestDataInt('id', 'GET', ''));
					$objData->setField('pincode', Service_Escape::requestDataInt('pincode', 'GET', ''));
					$objData->setField('e_mail', Service_Escape::requestDataString('e_mail', 'GET', ''));
					break;
				case 'wm_request.htm': // Форма оплаты по WebMoney
					$bookingId = Service_Escape::requestDataInt('ID_booking', 'GET', '');
					$objBooking = new Booking($bookingId);
					if ($objBooking->id && $objBooking->getField('other_payment_type') == 'WebMoney') {
						$objData->setField('LMI_PAYMENT_NO', $bookingId);
						$objData->setField('LMI_PAYMENT_AMOUNT', $objBooking->getBookingPrice('RUB') * 1.04);						
					}
					else User_Session::moveTo(W_ABSPATH . 'wm_pay.htm');
					break;				
			}
		}
		// Обрабатывает специальные статьи
		switch ($objArticle->getField('url')) {
			case 'cancellation.htm': // Отмена бронирования
				$this->bodyActionName = 'cancellation';
				break;
		}		
		*/
    // Заполняем title, description и т.д.    
	
	$this->title = $objArticle->getField('title');
    $this->description = $objArticle->getField('description');
    $this->keywords = $objArticle->getField('keywords');
    $this->pageHead = $objArticle->getField('article_name');
    //$this->canonical = W_FULLPATH . (Service_Translate::getLang() == 'en' ? 'eng/' : null) . $objArticle->getField('url');
    
    if (SimpleAdministration::isAdmin()) $this->editUrl = W_ADMIN . 'articles/edit/' . $objArticle->id . '/';
    
    $objViewArticle = new View_Article();
  	
    $this->showHeader();
    	echo '<div class="article content-container padd">';
			$objViewArticle->showArticle($objArticle);
      		$objViewArticle->showArticleForms($objArticle->getField('url'), $objData);
      echo '</div>';
    $this->showFooter();
	}
	
	/**
	 * Осущеcтвляем обработку форм
	 * 
	 * @param string $url - URL страницы
	 * @param Data $objData - Данные формы
	 */	
	public function processForm($url, Data $objData){
		Service_Debug::setDebug();
			switch ($url) {
			case 'contacts.htm': $this->processFeedForm($objData); break;
			case 'group_form.htm': $this->processGroupForm($objData); break;
			case 'cancellation.htm': $this->processCancellationForm($objData); break;
			case 'offertohotels_form.htm': $this->processOffertHotelForm($objData); break;
			case 'wm_pay.htm': $this->processWMPayForm($objData); break;
			case 'careers.htm': $this->processCareersForm($objData); break;
		}		
	}
	
	/**
	 * Осущеcтвляем обработку формы на странице "Контакты"
	 *
	 * @param Data $objData - Данные формы
	 */
	public function processFeedForm(Data $objData){
		Service_Debug::setDebug();
		$objDB = Service_Database::instance();
		$objData->validatesLengthOf = array(
				'e_mail' => array('minimum' => 2, 'maximum' => 128, 'message' => 'E-mail должен состоять из 2-128 символов'),
				'text' => array('minimum' => 2, 'maximum' => 1024, 'message' => 'Текст сообщения должен состоять из 2-1024 символов')
		);
		
		$objData->validatesFormatOf = array(
				'e_mail' => array('message' =>'E-mail заполнен неверно', 'with' => '|^[\.\-_A-Za-z0-9]+?@[\.\-A-Za-z0-9]+?\.[A-Za-z0-9]{2,6}$|')
		);
		
		$objData->fullValidation();
		if (!Exception_ActiveRecord::getExceptionsOfModel('Data')) {
			unset($objData->tableFields['save']);

			$arFieldValues = array('e_mail' => $objData->tableFields['e_mail'], 'text' => $objData->tableFields['text'], 'ID_user' => User_User::getId() ? User_User::getId() : null);
			$objDB->insert('question_notify', $arFieldValues);
			
			$objNotification = new User_Notification();
			$objNotification->feedback($objData->tableFields);
			
			unset($objData->tableFields['e_mail'],$objData->tableFields['text'],$_POST['Data']);
		}
	}
	
	/**
	 * Осущеcтвляем обработку формы группового бронирования
	 * 
	 * @param Data $objData - Данные формы
	 */	
	public function processGroupForm(Data $objData){
		Service_Debug::setDebug();
	  $objData->validatesLengthOf = array(
		  'first_name' => array('minimum' => 2, 'maximum' => 128, 'message' => 'Имя должно состоять из 2-128 символов'),
	  	'last_name' => array('minimum' => 2, 'maximum' => 128, 'message' => 'Фамилия должна состоять из 2-128 символов'),
		  'country' => array('minimum' => 2, 'maximum' => 128, 'message' => 'Страна должна состоять из 2-128 символов'),
	  	'city' => array('minimum' => 2, 'maximum' => 128, 'message' => 'Город должен состоять из 2-128 символов'),  
	  	'date_arr' => array('minimum' => 5, 'maximum' => 128, 'message' => 'Дата заезда указана неверно'),  
	  	'date_dep' => array('minimum' => 5, 'maximum' => 128, 'message' => 'Дата выезда указана неверно'),  
	  );	
	  $objData->validatesPresenceOf = array(
	  	'payment' => array('message' => 'Не выбрана форма оплаты'),
	  );	  
	  $objData->fullValidation();
		if (!Exception_ActiveRecord::getExceptionsOfModel('Data')) {
			unset($objData->tableFields['save']);
			$objNotification = new User_Notification();
			$objNotification->groupBooking($objData->tableFields);		
		}		  	  
	}		
	
	/**
	 * Осущеcтвляем обработку формы отмены бронирования
	 * 
	 * @param Data $objData - Данные формы
	 */	
	public function processCancellationForm(Data $objData) {
		Service_Debug::setDebug();
	  $objData->validatesLengthOf = array(
		  'id' => array('minimum' => 2, 'maximum' => 128, 'fieldName' => Service_Translate::getText('Номер маршрута')),
	  	'pincode' => array('minimum' => 2, 'maximum' => 128, 'fieldName' => Service_Translate::getText('PIN-код для отмены заказа')),
	  	'cancel_comment' => array('minimum' => 5, 'maximum' => 4096, 'fieldName' => Service_Translate::getText('Комментарий')),
	  );	
	  $objData->validatesFormatOf = array(
	    'e_mail' => array('message' => Service_Translate::getText('E-Mail введен неверно'), 'with' => $objData->eMailRegExp),
	  );	  
	  $objData->fullValidation();
		if (!Exception_ActiveRecord::getExceptionsOfModel('Data')) {
			$objBooking = new Booking();
			$objBooking->find('first', array('conditions' => "id = '" . $objData->getField('id') . "'"));
			try {
				if (!$objBooking->id) throw new Exception(Service_Translate::getText('Не существует заказа с таким ID'));
				if ($objBooking->getField('is_cancelled')) throw new Exception(Service_Translate::getText('Заказ уже отменен'));
				if ($objBooking->getField('pincode') != $objData->getField('pincode')) throw new Exception(Service_Translate::getText('Неверно введен PIN'));
				$curDate = Service_Date::changeDateFormat(Service_Date::gTime(), 'U', 'Y-m-d'); 
				if ($objBooking->getField('date_dep') <= $curDate) throw new Exception(Service_Translate::getText('Даты бронирования уже прошли'));
				// Отмена бронирования
				if ($objBooking->getField('is_our')) { // Наше бронирование
					if (!$objBooking->cancelOurBooking()) {
						$objDebug = new Debug();
				  	$objDebug->setFields(array('debug_name' => 'Our booking cancell error', 'debug_text' => $objBooking));
				  	$objDebug->save();
						throw new Exception(Service_Translate::getText('Невозможно отменить заказ'));
					}	
				}
				else { // Бронирование букинга
					$objServiceBooking = new Service_Booking();
					if ($objBooking->getField('payment_type') != 'Another') {
						$arrResult = $objServiceBooking->cancelBooking($objBooking->getField('id'), $objBooking->getField('pincode'));
						// Проверяем на ошибки
						if (isset($arrResult['fault'])) {
							if ($arrResult['fault']['string'] == 'bookings.cancelBooking: this booking is already cancelled') {
								$objBooking->updateFields(array(
									'is_cancelled' => true,
									'cancel_comment' => $objData->getField('cancel_comment')
								));
								if (!$objBooking->getField('cancelled_at')) $objBooking->updateField('cancelled_at', Service_Date::gLocalTime2BD());
								throw new Exception(Service_Translate::getText('Заказ уже отменен'));
							}
							$objDebug = new Debug();
							$objBooking->setField('result', $arrResult);
				  		$objDebug->setFields(array('debug_name' => 'Booking cancell unknown error', 'debug_text' => $objBooking));
				  		$objDebug->save();
							throw new Exception(Service_Translate::getText('Невозможно отменить заказ'));					
						}
						if (!isset($arrResult[0]['id']) || $arrResult[0]['id'] != $objBooking->getField('id')){
							$objDebug = new Debug();
							$objBooking->setField('result', $arrResult);
				  		$objDebug->setFields(array('debug_name' => 'Booking cancell error', 'debug_text' => $objBooking));
				  		$objDebug->save();
							throw new Exception(Service_Translate::getText('Невозможно отменить заказ'));
						}	
					}
				}
				// Все отлично сработало
				$objBooking->updateFields(array(
					'is_cancelled' => true,
					'cancelled_at' => Service_Date::gLocalTime2BD(),
					'cancel_comment' => $objData->getField('cancel_comment')
				));
				// Отправляем уведомления
				$objNotification = new User_Notification();
				$hotelClass = $objBooking->getField('is_our') ? 'OurHotel' : 'Hotel';
				$objHotel = new $hotelClass($objBooking->getField('ID_hotel'));
				$objNotification->cancellation($objData->getField('e_mail'), $objBooking, $objHotel);
				if ($objBooking->getField('is_our') && $objBooking->getField('payment_type') != 'Another') {
					$objNotification->cancellationToHotel($objBooking, $objHotel);
				}
			}
			catch (Exception $e) {
				Exception_ActiveRecord::addObjectException('Data', 'error', $e->getMessage());
			}
		}		  	  
	}		
	
	/**
	 * Осущеcтвляем обработку формы оплаты по WebMoney
	 * 
	 * @param Data $objData - Данные формы
	 */	
	public function processWMPayForm(Data $objData) {
		Service_Debug::setDebug();
		$objData->validatesLengthOf = array(
		  'ID_booking' => array('minimum' => 1, 'maximum' => 12, 'fieldName' => Service_Translate::getText('Введите номер платежа'))
	  );
	  $objData->validatesFormatOf = array(
	    'ID_booking' => array('message' => Service_Translate::getText('Неверный номер платежа'), 'with' => "/^[0-9]+$/"),
	  );	  	  
	  $objData->fullValidation();
		if (!Exception_ActiveRecord::getExceptionsOfModel('Data')) {
			$objBooking = new Booking($objData->getField('ID_booking'));
			if (!$objBooking->id || $objBooking->getField('other_payment_type') != 'WebMoney') Exception_ActiveRecord::addObjectException('Data', 'ID_booking', Service_Translate::getText('Неверный номер платежа'));
			else {
				User_Session::moveTo(View_Base::getLanguageUrl(W_ABSPATH . 'wm_request.htm?ID_booking=' . $objBooking->id));
			}
		}		  	  
	}
	
	/**
	 * Осущеcтвляем обработку формы сотрудничества
	 * 
	 * @param Data $objData - Данные формы
	 */	
	public function processOffertHotelForm(Data $objData) {
		Service_Debug::setDebug();
		$objData->validatesLengthOf = array(
		  'hotel_name' => array('minimum' => 2, 'maximum' => 128, 'fieldName' => Service_Translate::getText('Название гостиницы')),
		  'class' => array('minimum' => 2, 'maximum' => 128, 'fieldName' => Service_Translate::getText('Категория')),
		  'room_amount' => array('minimum' => 2, 'maximum' => 10, 'fieldName' => Service_Translate::getText('Количество номеров')),
		  'address' => array('minimum' => 2, 'maximum' => 128, 'fieldName' => Service_Translate::getText('Адрес')),
		  'city' => array('minimum' => 2, 'maximum' => 128, 'fieldName' => Service_Translate::getText('Город')),
		  'zip' => array('minimum' => 2, 'maximum' => 10, 'fieldName' => Service_Translate::getText('Почтовый индекс')),
		  'country' => array('minimum' => 2, 'maximum' => 64, 'fieldName' => Service_Translate::getText('Страна')),
		  'phone' => array('minimum' => 2, 'maximum' => 24, 'fieldName' => Service_Translate::getText('Телефон')),
		  'fax' => array('minimum' => 2, 'maximum' => 24, 'fieldName' => Service_Translate::getText('Факс')),
		  'contact_person' => array('minimum' => 2, 'maximum' => 128, 'fieldName' => Service_Translate::getText('Контактное лицо')),
	  );
	  $objData->validatesFormatOf = array(
	    'e_mail' => array('allowNull' => true, 'message' => Service_Translate::getText('E-Mail введен неверно'), 'with' => $objData->eMailRegExp),
	  );	  
	  $objData->fullValidation();
		if (!Exception_ActiveRecord::getExceptionsOfModel('Data')) {
			unset($objData->tableFields['save']);
			$objNotification = new User_Notification();
			$objNotification->offertHotel($objData->tableFields);
			User_Session::moveTo(View_Base::getLanguageUrl(W_ABSPATH . 'offertohotels_form.htm'), Service_Translate::getText('Заявка успешно отправлена'), 1);
		}		  	  
	}
	
	/**
	 * Осущеcтвляем обработку формы подачи резюме
	 * 
	 * @param Data $objData - Данные формы
	 */	
	public function processCareersForm(Data $objData) {
		Service_Debug::setDebug();
		$objData->validatesLengthOf = array(
		  'comment' => array('minimum' => 20, 'fieldName' => 'Комментарий'),
		  'phone' => array('minimum' => 7, 'fieldName' => 'Телефон'),
	  );
	  $objData->validatesFormatOf = array(
	    'e_mail' => array('message' => Service_Translate::getText('E-Mail введен неверно'), 'with' => $objData->eMailRegExp),
	  );	  
	  $objData->fullValidation();
		if (!Exception_ActiveRecord::getExceptionsOfModel('Data')) {
			$objNotification = new User_Notification();
			$objNotification->careers($objData->tableFields);
			User_Session::moveTo(View_Base::getLanguageUrl(W_ABSPATH . 'careers.htm#careers-form'), Service_Translate::getText('Заявка успешно отправлена'), 1);
		}		  	  
	}
  
  /**
   * Отображает данные о ревизии 
   */
  public function actionRevision() {
  	Service_Debug::setDebug();
  	if (!SimpleAdministration::isAdmin()) throw new Exception_SiteError(403);
	  // Получаем инфу
  	$arrRevisionInfo = file(ABSPATH . '.svn/entries');	  
	  if (empty($arrRevisionInfo)) throw new Exception_SiteError(404);
	  
	  $objViewBlock = new View_Block();
	  $objViewBlock->showRevision($arrRevisionInfo);	
  }
	
}